package com.ophiux.utils.common;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * 说明：时间工具类<br>
 * <h1>创 建 人: hehailong<br>
 * </h1> 创建日期: 2018年8月15日 上午11:44:01<br>
 * 修改记录：
 */
public class DateUtil {

	public enum DateFormat {
		/**
		 * yyyy-MM-DD HH:mm:ss
		 */
		YYYY_MM_DD_HH_mm_ss,
		/**
		 * YYYY-MM-DD
		 */
		YYYY_MM_DD,

		/**
		 * yyyyMMDDHHmmss
		 */
		YYYYMMDDHHMMSS,

		YYYY,

		EEEE; // 星期

	}

	private final static SimpleDateFormat df_yyyy_MM_dd = new SimpleDateFormat("yyyy-MM-dd");
	private final static SimpleDateFormat YYYY_MM_DD_HH_mm_ss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private final static SimpleDateFormat YYYYMMDDHHMMSS = new SimpleDateFormat("yyyyMMddHHmmss");
	private final static SimpleDateFormat YYYY = new SimpleDateFormat("yyyy");
	private final static SimpleDateFormat EEEE = new SimpleDateFormat("EEEE");

	/**
	 * 
	 * Description: 格式化字符串时间
	 * 
	 * @param date
	 * @param dateFormat
	 * @return
	 */
	public static String getStrDate(Date date, DateFormat dateFormat) {
		if (date == null) {
			date = new Date();
		}
		switch (dateFormat) {
		case YYYY_MM_DD_HH_mm_ss:
			return YYYY_MM_DD_HH_mm_ss.format(date);
		case YYYYMMDDHHMMSS:
			return YYYYMMDDHHMMSS.format(date);
		case YYYY_MM_DD:
			return df_yyyy_MM_dd.format(date);
		case YYYY:
			return YYYY.format(date);

		case EEEE:
			return EEEE.format(date);

		default:
			break;
		}
		return "";
	}

	/**
	 * 
	 * Description: 格式化字符串时间
	 * 
	 * @param date
	 * @param dateFormat
	 * @return
	 * @throws ParseException
	 */
	public static Date getDate(String dateStr, DateFormat dateFormat) throws ParseException {
		switch (dateFormat) {
		case YYYY_MM_DD_HH_mm_ss:
			return YYYY_MM_DD_HH_mm_ss.parse(dateStr);

		case YYYY_MM_DD:
			return df_yyyy_MM_dd.parse(dateStr);

		case EEEE:
			return EEEE.parse(dateStr);

		default:
			return df_yyyy_MM_dd.parse(dateStr);
		}
	}


	/**
	 * java 偏移时间
	 * 
	 * @param starDate
	 * @param leadValue
	 * @return
	 */
	public static Date getLeadDay(Date starDate, int leadValue) {
		GregorianCalendar gc = new GregorianCalendar();
		if (starDate != null) {
			gc.setTime(starDate);
		}
		gc.add(5, leadValue);
		return gc.getTime();

	}

	/**
	 * 
	 * Description: 是不是今天<br>
	 * 
	 * @param dateStr
	 *            格式YYYY-MM-DD
	 * @return
	 */
	public static boolean isToday(String dateStr) {
		return getStrDate(new Date(), DateFormat.YYYY_MM_DD).equals(dateStr);
	}

	/**
	 * 
	 * Description: 时间比较
	 * 
	 * @param date 比较的时间
	 * @param xzsj_date  限制时间
	 * @return  如果date>=xzsj_date,返回true。否则返回false
	 */
	public static boolean sjbj(Date date, Date xzsj_date) {
		if (date.getTime() < xzsj_date.getTime()) { // 比较的 时间 小于 限制时间
			return false;
		} else {//比较的 时间 大于等于 限制时间
			return true;
		}
	}

	/**
	 * Description: 时间比较
	 * @param date 比较的时间
	 * @param xzsj_date  限制时间
	 * @return  如果date>=xzsj_date,返回true。否则返回false
	 */
	public static boolean sjbj(String dateStr, String xzsj_dateStr) {
		return sjbj(convertDate(dateStr, "yyyy-MM-dd"), convertDate(xzsj_dateStr, "yyyy-MM-dd"));
	}

	/*
	 * public static void main(String[] args) {
	 * System.out.println(getAge("19951010","20190124")); }
	 */

	/**
	 * 获取当前时间 2018-08-13 陈辉
	 * 
	 * @return YYYY-MM-DD HH:mm:ss
	 */
	public static String getCurDateStr() {
		return getStrDate(new Date(), DateFormat.YYYY_MM_DD_HH_mm_ss);
	}

	/**
	 * 获取随机时间
	 * 
	 * @return YYYYMMDDHHMMSS
	 */
	public static String getCurDateRandom() {
		return getStrDate(new Date(), DateFormat.YYYYMMDDHHMMSS);
	}

	/**
	 * 根据日期获取星期
	 * 
	 * @param date
	 * @return
	 */
	public static String getStrDay(Date date) {
		return getStrDate(date, DateFormat.EEEE);
	}

	public static String getAge(String birthday) {
		String ageStr = "";

		try {
			/*
			 * if(StringUtil.isEmpty(birthday)) { return ageStr; }
			 */
			if (birthday == null || birthday.equals(""))
				return ageStr;

			Date birthdate = new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
			GregorianCalendar currentDay = new GregorianCalendar();
			currentDay.setTime(birthdate);
			int year = currentDay.get(Calendar.YEAR);
			int month = currentDay.get(Calendar.MONTH);
			int day = currentDay.get(Calendar.DAY_OF_MONTH);
			// 获取年龄
			String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
			Calendar c = Calendar.getInstance();// 可以对每个时间域单独修改
			int Year = c.get(Calendar.YEAR);
			int Month = c.get(Calendar.MONTH);
			int Day = c.get(Calendar.DATE);
			int age = Year - year;
			if (Month + 1 < month || month == Month && Day < day) {
				age--;
			}
			ageStr = age + "";
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ageStr;
	}

	/**
	 * 计算年龄 格式：YYYY-MM-DD
	 * 
	 * @param date1
	 *            开始时间
	 * @param date2
	 *            结束时间
	 * @return
	 */
	public static String getAge(String date1, String date2) {
		String ageStr = "";

		try {
			if (StringUtil.isEmpty(date1) || StringUtil.isEmpty(date2)) {
				return ageStr;
			}

			Date birthdate = new SimpleDateFormat("yyyy-MM-dd").parse(date1);
			GregorianCalendar currentDay = new GregorianCalendar();
			currentDay.setTime(birthdate);
			int year = currentDay.get(Calendar.YEAR);
			int month = currentDay.get(Calendar.MONTH);
			int day = currentDay.get(Calendar.DAY_OF_MONTH);

			// 获取年龄
			Date birthdate2 = new SimpleDateFormat("yyyy-MM-dd").parse(date2);
			GregorianCalendar currentDay2 = new GregorianCalendar();
			currentDay2.setTime(birthdate2);

			Calendar c = Calendar.getInstance();// 可以对每个时间域单独修改
			int Year = c.get(Calendar.YEAR);
			int Month = c.get(Calendar.MONTH);
			int Day = c.get(Calendar.DATE);
			int age = Year - year;
			if (Month + 1 < month || month == Month && Day < day) {
				age--;
			}
			ageStr = age + "";
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ageStr;
	}

	/**
	 * 把日期字符串格式化成日期类型
	 * 
	 * @param dateStr
	 *            日期字符串
	 * @param format
	 *            时间格式
	 * @return
	 */
	public static Date convertDate(String dateStr, String format) {
		SimpleDateFormat simple = new SimpleDateFormat(format);
		try {
			simple.setLenient(false);
			return simple.parse(dateStr);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 把日期类型格式化成字符串
	 * 
	 * @param date
	 *            日期
	 * @param format
	 *            时间格式
	 * @return
	 */
	public static String convertString(Date date, String format) {
		SimpleDateFormat format1 = new SimpleDateFormat(format);
		try {
			return format1.format(date);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 转sql的time格式
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static java.sql.Timestamp convertSqlTime(Date date) {
		return new java.sql.Timestamp(date.getTime());
	}

	/**
	 * 转sql的日期格式
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public static java.sql.Date convertSqlDate(Date date) {
		return new java.sql.Date(date.getTime());
	}

	/**
	 * 获取当前日期
	 * 
	 * @param format
	 *            时间格式
	 * @return
	 */
	public static String getCurrentDate(String format) {
		return new SimpleDateFormat(format).format(new Date());
	}

	/**
	 * 获取时间戳
	 * 
	 * @return
	 */
	public static long getTimestamp() {
		return System.currentTimeMillis();
	}

	/**
	 * 获取月份的天数
	 */
	public static int getDaysOfMonth(int year, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, 1);
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取日期的年
	 */
	public static int getYear(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.YEAR);
	}

	/**
	 * 获取日期的月
	 */
	public static int getMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH) + 1;
	}

	/**
	 * 获取日期的日
	 */
	public static int getDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DATE);
	}

	/**
	 * 获取日期的时
	 */
	public static int getHour(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.HOUR);
	}

	/**
	 * 获取日期的分种
	 */
	public static int getMinute(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.MINUTE);
	}

	/**
	 * 获取日期的秒
	 */
	public static int getSecond(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.SECOND);
	}

	/**
	 * 获取星期几
	 */
	public static int getWeekDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
		return dayOfWeek - 1;
	}

	/**
	 * 获取哪一年共有多少周
	 */
	public static int getMaxWeekNumOfYear(int year) {
		Calendar c = new GregorianCalendar();
		c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
		return getWeekNumOfYear(c.getTime());
	}

	/**
	 * 取得某天是一年中的多少周
	 */
	public static int getWeekNumOfYear(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setMinimalDaysInFirstWeek(7);
		c.setTime(date);
		return c.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 取得某天所在周的第一天
	 */
	public static Date getFirstDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
		return c.getTime();
	}

	/**
	 * 取得某天所在周的最后一天
	 */
	public static Date getLastDayOfWeek(Date date) {
		Calendar c = new GregorianCalendar();
		c.setFirstDayOfWeek(Calendar.MONDAY);
		c.setTime(date);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
		return c.getTime();
	}

	/**
	 * 取得某年某周的第一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周,2009-01-05为2009年第一周的第一天
	 */
	public static Date getFirstDayOfWeek(int year, int week) {
		Calendar calFirst = Calendar.getInstance();
		calFirst.set(year, 0, 7);
		Date firstDate = getFirstDayOfWeek(calFirst.getTime());

		Calendar firstDateCal = Calendar.getInstance();
		firstDateCal.setTime(firstDate);

		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, (week - 1) * 7);
		firstDate = getFirstDayOfWeek(cal.getTime());

		return firstDate;
	}

	/**
	 * 取得某年某周的最后一天 对于交叉:2008-12-29到2009-01-04属于2008年的最后一周, 2009-01-04为
	 * 2008年最后一周的最后一天
	 */
	public static Date getLastDayOfWeek(int year, int week) {
		Calendar calLast = Calendar.getInstance();
		calLast.set(year, 0, 7);
		Date firstDate = getLastDayOfWeek(calLast.getTime());

		Calendar firstDateCal = Calendar.getInstance();
		firstDateCal.setTime(firstDate);

		Calendar c = new GregorianCalendar();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, Calendar.JANUARY);
		c.set(Calendar.DATE, firstDateCal.get(Calendar.DATE));

		Calendar cal = (GregorianCalendar) c.clone();
		cal.add(Calendar.DATE, (week - 1) * 7);

		return getLastDayOfWeek(cal.getTime());
	}

	private static Date add(Date date, int calendarField, int amount) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		} else {
			Calendar c = Calendar.getInstance();
			c.setTime(date);
			c.add(calendarField, amount);
			return c.getTime();
		}
	}

	/*
	 * 1则代表的是对年份操作， 2是对月份操作， 3是对星期操作， 5是对日期操作， 11是对小时操作， 12是对分钟操作， 13是对秒操作， 14是对毫秒操作
	 */

	/**
	 * 增加年
	 */
	public static Date addYears(Date date, int amount) {
		return add(date, 1, amount);
	}

	/**
	 * 增加月
	 */
	public static Date addMonths(Date date, int amount) {
		return add(date, 2, amount);
	}

	/**
	 * 增加周
	 */
	public static Date addWeeks(Date date, int amount) {
		return add(date, 3, amount);
	}

	/**
	 * 增加天
	 */
	public static Date addDays(Date date, int amount) {
		return add(date, 5, amount);
	}

	/**
	 * 增加时
	 */
	public static Date addHours(Date date, int amount) {
		return add(date, 11, amount);
	}

	/**
	 * 增加分
	 */
	public static Date addMinutes(Date date, int amount) {
		return add(date, 12, amount);
	}

	/**
	 * 增加秒
	 */
	public static Date addSeconds(Date date, int amount) {
		return add(date, 13, amount);
	}

	/**
	 * 增加毫秒
	 */
	public static Date addMilliseconds(Date date, int amount) {
		return add(date, 14, amount);
	}

	/**
	 * time差
	 */
	public static long diffTimes(Date before, Date after) {
		return after.getTime() - before.getTime();
	}

	/**
	 * 秒差
	 */
	public static long diffSecond(Date before, Date after) {
		return (after.getTime() - before.getTime()) / 1000;
	}

	/**
	 * 分种差
	 */
	public static int diffMinute(Date before, Date after) {
		return (int) (after.getTime() - before.getTime()) / 1000 / 60;
	}

	/**
	 * 时差
	 */
	public static int diffHour(Date before, Date after) {
		return (int) (after.getTime() - before.getTime()) / 1000 / 60 / 60;
	}

	/**
	 * 天数差
	 */
	public static int diffDay(Date before, Date after) {
		return Integer.parseInt(String.valueOf(((after.getTime() - before.getTime()) / 86400000)));
	}

	/**
	 * 月差
	 */
	public static int diffMonth(Date before, Date after) {
		int monthAll = 0;
		int yearsX = diffYear(before, after);
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(before);
		c2.setTime(after);
		int monthsX = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
		monthAll = yearsX * 12 + monthsX;
		int daysX = c2.get(Calendar.DATE) - c1.get(Calendar.DATE);
		if (daysX > 0) {
			monthAll = monthAll + 1;
		}
		return monthAll;
	}

	/**
	 * 年差
	 */
	public static int diffYear(Date before, Date after) {
		return getYear(after) - getYear(before);
	}

	/**
	 * 设置23:59:59
	 */
	public static Date setEndDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return calendar.getTime();
	}

	/**
	 * 设置00:00:00
	 */
	public static Date setStartDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 00);
		calendar.set(Calendar.MINUTE, 00);
		calendar.set(Calendar.SECOND, 00);
		return calendar.getTime();
	}

	/**
	 * 设置时分秒
	 * 
	 * @param date
	 * @return
	 */
	public static Date setTime(Date date, int hour, int minute, int second) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, hour);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, second);
		return calendar.getTime();
	}

	/**
	 * 获取当天的星期
	 * 
	 * @return
	 */
	public static String getCurDay() {
		return getStrDay(new Date());
	}

	/**
	 * java 偏移时间-分钟数
	 * 
	 * @param starDate
	 * @param leadValue
	 * @return
	 */
	public static Date getLeadMinute(Date starDate, int leadValue) {
		GregorianCalendar gc = new GregorianCalendar();
		if (starDate != null) {
			gc.setTime(starDate);
		}

		gc.add(Calendar.MINUTE, leadValue);
		return gc.getTime();

	}

	/**
	 * 说明：与系统时间比较大小<br>
	 * 创 建 人: <b>hehailong</b>
	 * 
	 * @param time
	 * @return true：比系统时间打 false：比系统时间小
	 */
	public static boolean compareTime(String time) {
		try {
			if (YYYY_MM_DD_HH_mm_ss.parse(time).getTime() > new Date().getTime()) {
				return true;
			} else {
				return false;
			}
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 比较前者时间是否小于后者时间
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static boolean compareTime(String startTime,String endTime) {
		try {
			if (YYYY_MM_DD_HH_mm_ss.parse(startTime).getTime() < YYYY_MM_DD_HH_mm_ss.parse(endTime).getTime()) {
				return true;
			} else {
				return false;
			}
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 获取指定月份的起止日期 2019-06-04 chenh 新增
	 * 
	 * @param 年月
	 * @return
	 */
	public static String[] GetMonthDaysPeriod(int year, int month) {

		String sDate = "", eDate = "";

		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month - 1);

		String monthStr = month < 10 ? "0" + month : month + "";
		// 当月第一天
		// calendar.set(Calendar.DAY_OF_MONTH, 1);
		String sday = calendar.getActualMinimum(Calendar.DAY_OF_MONTH) + "";// 获取日
		sday = Integer.parseInt(sday) < 10 ? "0" + sday : sday + "";
		sDate = year + "-" + monthStr + "-" + sday;

		// 当月最后一天
		String eday = calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + "";// 获取日
		eday = Integer.parseInt(eday) < 10 ? "0" + eday : eday + "";

		eDate = year + "-" + monthStr + "-" + eday;

		return new String[] { sDate, eDate };
	}

	/**
	 * 说明：获取北京当前时间<br>
	 * 创 建 人: <b>hehailong</b><br>
	 * 
	 * @return String yyyy-MM-dd HH:mm:ss
	 * @throws Exception
	 */
	public static String getBJCurrentStrTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = getBJCurrentTime();
		System.out.println(date.getTime());
		return sdf.format(date);
	}

	/**
	 * 说明：获取北京当前时间<br>
	 * 创 建 人: <b>hehailong</b><br>
	 * 
	 * @return Date
	 * @throws Exception
	 */
	public static Date getBJCurrentTime() {
		try {
			TimeZone.setDefault(TimeZone.getTimeZone("GMT+8")); // 时区设置
			URL url = new URL("http://time.tianqi.com");// 取得资源对象
			URLConnection uc = url.openConnection();// 生成连接对象
			uc.connect(); // 发出连接
			long ld = uc.getDate(); // 取得网站日期时间
			Date date = new Date(ld); // 转换为标准时间对象
			return date;
		} catch (Exception e) {
			e.printStackTrace();
			return new Date();// 返回服务器当前时间
		}
	}

	/**
	 * 计算相差天数
	 * 
	 * @param startDate
	 *            开始时间
	 * @param endDate
	 *            结束时间
	 * @return
	 */
	public static int differentDays(Date startDate, Date endDate) {
		Calendar calendar1 = Calendar.getInstance();
		calendar1.setTime(startDate);
		Calendar calendar2 = Calendar.getInstance();
		calendar2.setTime(endDate);

		int day1 = calendar1.get(Calendar.DAY_OF_YEAR);
		// System.out.println(day1);
		int day2 = calendar2.get(Calendar.DAY_OF_YEAR);
		// System.out.println(day2);
		int year1 = calendar1.get(Calendar.YEAR);
		int year2 = calendar2.get(Calendar.YEAR);

		if (year1 != year2) { // 不同年
			int timeDistance = 0;
			for (int i = year1; i < year2; i++) { // 闰年
				if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
					timeDistance += 366;
				} else { // 不是闰年
					timeDistance += 365;
				}
			}
			return timeDistance + (day2 - day1);
		} else {// 同年
			return day2 - day1;
		}

	}

	public static int differentDayMillisecond(Date date1, Date date2) {
		int day = (int) ((date2.getTime() - date1.getTime()) / (3600 * 1000 * 24));
		return day;
	}

	public static void main(String[] args) throws IOException {
//		String arr[] = GetMonthDaysPeriod(2019, 6);
//		System.out.println("开始：" + arr[0] + "\n 结束：" + arr[1]);
//		System.out.println(getBJCurrentStrTime());
//		boolean ss = sjbj(convertDate("2020-06-22", "yyyy-MM-dd"), convertDate("2020-01-22", "yyyy-MM-dd"));
//		System.out.println(ss);
		
		int y = diffMonth(convertDate("2020-11-20", "yyyy-MM-dd"), new Date());
		System.out.println(y);
		
	}

}
